#ifndef TABLE_INCLUDED
#define TABLE_INCLUDED

#include <stddef.h>

#define T Table_T
typedef struct T *T;

extern T Table_new(size_t hint, int compare(const char *x, const char *y));

/**
 * creates, initializes, and returns a new associative table. The hint is an
 * estimate of the number of key-value pairs the tables is expected to hold. All
 * tables can hold an arbitrary number of pairs, but an implementation may use
 * hint to improve performance. The compare is used in subsequent calls to
 * Table_get and Table_put to compare keys; for keys x and y, compare(x, y) must
 * return 0 if x==y, a value < 0 ifif x < y, and a value > - if x > y. It is a
 * checked runtime error for compare to be NULL
 */

extern void Table_free(T *table);
/**
 * deallocates *table and its keys, but not its values, and sets *table to NULL.
 * It is a checked runtime error for table or *table to be NULL.
 */

extern void Table_put(T table, char *key, void *value);
/**
 * Adds the key-value pair to table, replacing the previous value associated with
 * key, if there is one. Key is copied
 */

extern void *Table_get(T table, char *key);
/**
 * returns the value associated with key, if it's in table. Otherwise, Table_get
 * returns NULL
 */

extern int Table_length(T table);
/**
 * Returns the number of key-value pairs in table.
 */

extern void Table_map(T table, void apply(char *key, void **value, void *cl), void *cl);
/**
 * calls apply for every key-value pair in tablel the second argument is a pointer
 * to the value associated with key, so apply can change the values. The apply and
 * cl are closure: clients can pass an application-specific pointer, cl, to Table_map
 * and this pointer is passed along to apply at each call. It is a checked runtime
 * error for apply to be NULL, or for apply to change the contents of table by
 * calling Table_put. It is an unchecked runtime error for apply to change the
 * string pointed to by key.
 *
 * It is a checked runtime error to pass a NULL key or table to any function in
 * this interface
 */

#undef T

#endif //TABLE_INCLUDED
